/**
 * Project Name:spring-cloud-pilot
 * File Name:DiscoveryClientConfigServiceBootstrapConfiguration.java
 * Package Name:org.spring.cloud.pilot.configuration
 * Date:2019年11月4日上午11:17:27
 * Copyright (c) 2019, dengqian37@126.com All Rights Reserved.
 *
 */

package org.spring.cloud.pilot.configuration;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.config.client.ConfigClientProperties;
import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;

/**
 * ClassName:DiscoveryClientConfigServiceBootstrapConfiguration <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON. <br/>
 * Date: 2019年11月4日 上午11:17:27 <br/>
 * @author dengqian
 * @version
 * @since JDK 1.8
 * @see
 */
@ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled", matchIfMissing = false)
@Configuration
@Import({ UtilAutoConfiguration.class })
@EnableDiscoveryClient
@Primary
public class DiscoveryClientConfigServiceBootstrapConfiguration {

    private static Log logger = LogFactory
            .getLog(DiscoveryClientConfigServiceBootstrapConfiguration.class);

    @Autowired
    private ConfigClientProperties config;

    @Autowired
    private ConfigServerInstanceProvider instanceProvider;

    private HeartbeatMonitor monitor = new HeartbeatMonitor();

    @Bean
    public ConfigServerInstanceProvider configServerInstanceProvider(
            DiscoveryClient discoveryClient) {
        return new ConfigServerInstanceProvider(discoveryClient);
    }

    @EventListener(ContextRefreshedEvent.class)
    public void startup(ContextRefreshedEvent event) {
        refresh();
    }

    @EventListener(HeartbeatEvent.class)
    public void heartbeat(HeartbeatEvent event) {
        if (monitor.update(event.getValue())) {
            refresh();
        }
    }

    private void refresh() {
        try {
            String serviceId = this.config.getDiscovery().getServiceId();
            ServiceInstance server = this.instanceProvider
                    .getConfigServerInstance(serviceId);
            String url = getHomePage(server);
            if (server.getMetadata().containsKey("password")) {
                String user = server.getMetadata().get("user");
                user = user == null ? "user" : user;
                this.config.setUsername(user);
                String password = server.getMetadata().get("password");
                this.config.setPassword(password);
            }
            if (server.getMetadata().containsKey("configPath")) {
                String path = server.getMetadata().get("configPath");
                if (url.endsWith("/") && path.startsWith("/")) {
                    url = url.substring(0, url.length() - 1);
                }
                url = url + path;
            }
            this.config.setUri(url);
        }
        catch (Exception ex) {
            if (config.isFailFast()) {
                throw ex;
            }
            else {
                logger.warn("Could not locate configserver via discovery", ex);
            }
        }
    }

    private String getHomePage(ServiceInstance server) {
        return server.getUri().toString() + "/";
    }

}


	